/*=============================================================================

  OSG APPLICATION MODULE

  FILE: sgs.h
  
  DESCRIPTION

    Module for Application

  EXTERNALIZED FUNCTIONS

    
  Copyright (c) DaeSung Engineering Inc. All rights reserved.

=============================================================================*/
/*=============================================================================

                             EDIT HISTORY

  ---------  -------  -------------------------------------------------------
    when       who     what, where, why
  ---------  -------  -------------------------------------------------------
   05/26/05   pkim    Version E01.0

=============================================================================*/

/*=============================================================================
  HEADER INCLUSION
=============================================================================*/
#include <mxBase.h>
#include <SYS_aux.h>

/*=============================================================================
  CONSTANT DEFINITION
=============================================================================*/
#define AUXMEM_TBL_MAX				(4) // TABLE SIZE
#define AUXMEM_LIST_SIZE				(512) // MEMORY NUM PER TABLE

/*=============================================================================
  STRUCTURE DEFINITION
=============================================================================*/
static MEMTBL_s		*memTbl[AUXMEM_TBL_MAX];

/*=============================================================================
  LOCALIZED FUNCTION DEFINITION
=============================================================================*/
static dword auxMem_CBF(dword cmd, dword wp, dword lp, void *ptr);

/*=============================================================================
  EXTERNALIZED FUNCTION IMPLEMENTATION
=============================================================================*/
void auxMem_Init(void)
{
	int32		j;

	for(j=0; j<AUXMEM_TBL_MAX; j++)
	{
		memTbl[j] = NULL;
	}
	memTbl[0] = memTbl_Create(0, AUXMEM_LIST_SIZE, auxMem_CBF);
}

void auxMem_Close(void)
{
	int32		j;

	for(j=0; j<AUXMEM_TBL_MAX; j++)
	{
		if(memTbl[j] != NULL)
		{
			memTbl_Destroy(memTbl[j]);
			memTbl[j] = NULL;
		}
	}
}

void *memCalloc_(dword siz, const char *pszFile, int32 nLine)
{
	void		*ptr;
	byte		j;

	for(j=0; j<AUXMEM_TBL_MAX; j++)
	{
		if(memTbl[j] == NULL)
		{
			memTbl[j] = memTbl_Create(j, AUXMEM_LIST_SIZE, auxMem_CBF);
		}
		ptr = memGet(memTbl[j], siz, 0, pszFile, nLine);
		if(ptr != NULL)
		{
			memZeros(ptr, siz);
			break;
		}
	}
	if(ptr == NULL)
	{
		if(pszFile != NULL)
		{
			LOGERR("[auxMem] Out of memory block(%s,%d)", pszFile, nLine);
		}
		else
		{
			LOGERR("[auxMem] Out of memory block");
		}
	}
	return	ptr;
}

void memFree_(void *ptr, const char *pszFile, int32 nLine)
{
	MEMHEADER_s		*h;
	
	if(memAssert(ptr) == FALSE)
	{
		if(ptr == NULL)
			return;
		
		if(pszFile != NULL)
		{
			LOGWARN("[auxMem] Try to free the invalid memory(%s,%d)", pszFile, nLine);
		}
		else
		{
			LOGWARN("[auxMem] Try to free the invalid memory");
		}
		return;
	}
	h = (MEMHEADER_s*)((byte*)ptr-sizeof(*h));

	if(!RANGE_IN(h->tblID, 0, (AUXMEM_TBL_MAX-1)))
	{
		if(pszFile != NULL)
		{
			LOGWARN("[auxMem] Try to free the invalid memory(%s,%d)", pszFile, nLine);
		}
		else
		{
			LOGWARN("[auxMem] Try to free the invalid memory");
		}
		return;
	}
	memPut(memTbl[h->tblID], ptr, pszFile, nLine);
}

void auxMem_Info(dword *tbl_num, dword *mem_num, dword *mem_siz, dword *res_num, dword *res_siz)
{
	int32		j;
	dword		mnum, msiz1, msiz2;
	dword		rnum, rsiz1, rsiz2;
	dword		tnum, tmnum, tmsiz, trnum, trsiz;

	tnum = 0;
	tmnum = tmsiz = 0;
	trnum = trsiz = 0;
	for(j=0; j<AUXMEM_TBL_MAX; j++)
	{
		if(memTbl[j] != NULL)
		{
			memTbl_Info(memTbl[j], &mnum, &msiz1, &msiz2, &rnum, &rsiz1, &rsiz2);
			tnum += 1;
			tmnum += mnum;
			tmsiz += msiz1;
			trnum += rnum;
			trsiz += rsiz1;
		}
	}
	*tbl_num = tnum;
	*mem_num = tmnum;
	*mem_siz = tmsiz;
	*res_num = trnum;
	*res_siz = trsiz;
}

void auxMem_Clear(dword *mem_num, dword *tot_siz)
{
	int32		j;
	dword		num, siz1, siz2;
	dword		tnum, tsiz;

	tnum = tsiz = 0;
	for(j=0; j<AUXMEM_TBL_MAX; j++)
	{
		if(memTbl[j] != NULL)
		{
			memTbl_Clear(memTbl[j], &num, &siz1, &siz2);
			tnum += num;
			tsiz += siz1;
		}
	}
	*mem_num = tnum;
	*tot_siz = tsiz;
}

void auxMem_Dump(mcxt fp)
{
	int32			j;
	dword			k, num, siz;
	MEMTBL_s		*tbl;
	MEM_s			*mem;
	MEMHEADER_s	*h;
	
	if(fp == NULL)
		return;

	// CLEAR.1ST
	auxMem_Clear(&num, &siz);
	
	FileIo_Printf(fp,"======================== aux.mem.status\r\n");
	for(j=0; j<AUXMEM_TBL_MAX; j++)
	{
		if(memTbl[j] == NULL)
			continue;

		tbl = memTbl[j];
		if(tbl->que == NULL)
			continue;

memLock(tbl);
		mem = tbl->que;
		for(k=0; k<tbl->tblSIZ; k++, mem++)
		{
			if(mem->ptr)
			{
				h = MEMHEADER(mem);
				if(h->alloc == 0xFF)
				{
					if(mem->fname)
					{
						FileIo_Printf(fp, "tID=%002d, mID=%00004d, mem=0x%000000008X, siz=%d, line%d @ %s\r\n", \
								h->tblID, h->memID, (byte*)mem->ptr+sizeof(*h), h->siz1, \
								mem->fline, mem->fname);
					}
					else
					{
						FileIo_Printf(fp, "tID=%002d, mID=%00004d, mem=0x%000000008X, siz=%d\r\n",\
								h->tblID, h->memID, (byte*)mem->ptr+sizeof(*h), h->siz1);
					}
				}
			}
		}
memUnlock(tbl);
	}
}

/*=============================================================================
  LOCALIZED FUNCTION IMPLEMENTATION
=============================================================================*/
dword auxMem_CBF(dword cmd, dword wp, dword lp, void *ptr)
{
	switch(cmd)
	{
	case MEM_ALLOC_C:
	{
		return	(dword)osCalloc(wp);
	}
	case MEM_REALLOC_C:
	{
		if(ptr != NULL)
		{
			osFree(ptr);
		}
		return	(dword)osCalloc(wp);
	}
	case MEM_FREE_C:
	{
		if(ptr != NULL)
		{
			osFree(ptr);
		}
		break;
	}
	case MEM_ERROR_C:
	{
		LOGWARN("[auxMem] Memory internal handling error");
		break;
	}
	}

	return	(0);
}


/*--- END OF osg_aux.cpp ---*/
